require "scripts.少年光头.Helper.deepcopy"
require "scripts.少年光头.UiHelper.UiHelper"
require "scripts.少年光头.GTBar.GTBar"
require "scripts.少年光头.Helper.hlua.himage"
monsterZone = {}
---刷怪房
monsterZone = require "scripts.少年光头.Helper.classic":extend()

---刷怪房信息
monsterZone.info = {
    ---区域Name
    ["区域Name"] = monsterZone.area
}
---刷怪房怪物列表
monsterZone.Monsters = {}
monsterZone.Monsters["怪物名字"] = {
    ---怪物名字
    Name = "",
    ---怪物创建事件 精英怪事件
    CreateEvent = function(uid)
    end,
    ---自定义死亡事件 收益事件等
    DeadEvent = function(uid)
    end,
    ---Ai
    Ai = {}
}
---刷怪区域
monsterZone.area = {
    ---区域ID
    rectID = 0,
    ---当前区域生成会生成的怪
    MonsterNames = "怪物",
    ---当前区域生成的怪
    Monsters = {
        ["怪物ID"] = {
            Name = "怪物名字",
            ---死亡事件ID(自动创建,不可自定义)
            deadEventID = {},
           
        }
    },
    ---敌对玩家序号
    No = 11,
    ---怪物清空事件
    AllMonstersRemoveEvent = {},
    ---所有数量生成完成事件
    AllMonstersCreateEvent = function(Monsters)
    end,
    ---怪物数量
    CreateMonstersNumber = 10,
    ---怪物难度 按倍数增加属性 收益
    Difficulty = 0,
    ---AI难度 0自动施法 1根据行为判断
    AiDifficulty = 0,
    ---清空怪物之后生成所需刷新时间/s  防守刷怪每刷一只时间
    Refresh = 0
}
function monsterZone:new()
    self.info = {}
    self.Monsters = {}
    self.area = {}
    return self
end

---@class unitid 单位ID

---添加怪物
---@param name string 物编单位名字
---@param CreateEvent fun(unitid:unitid):void 怪物创建事件 精英怪事件
---@param DeadEvent fun(unitid:unitid):void 自定义死亡事件 收益事件等
---@param Ai fun(unitid:unitid):void
function monsterZone:AddMonsters(name, createEvent, deadEvent, ai)
    table.insert(
        self.Monsters,
        {
            Name = name,
            CreateEvent = createEvent,
            DeadEvent = deadEvent,
            Ai = ai
        }
    )
    return self
end

---创建刷怪区
---@param x number
---@param y number
---@param w number 长
---@param h number 宽
---@param rcname string 区名字
---@param monsterNames string 生成的怪物
---@param no number 队伍名字
---@param allMonstersRemoveEvent fun(Monsters所有怪物):void 怪物清空事件
---@param allMonstersCreateEvent fun(Monsters所有怪物):void 所有数量生成完成事件
---@param createMonstersNumber number 怪物数量
---@param difficulty number 怪物难度 按倍数增加属性 收益
---@param aiDifficulty number AI难度 0自动施法 1根据行为判断
---@param refresh number 刷新时间 0表示 所有怪物死亡后直接刷新
---@return self
function monsterZone:CreateArea(
    x,
    y,
    w,
    h,
    rcname,
    no,
    allMonstersRemoveEvent,
    allMonstersCreateEvent,
    createMonstersNumber,
    difficulty,
    aiDifficulty,
    refresh)
    w = w or 500
    h = h or 500
    createMonstersNumber = createMonstersNumber or 0
    difficulty = difficulty or 0
    aiDifficulty = aiDifficulty or 0
    local rc = hrect.create(x, y, w, h, rcname)
    monsterZone.info[rcname] = {
        ---区域ID
        rectID = rc,
        ---当前区域生成会生成的怪
        MonsterNames = {},
        ---当前区域生成的怪
        Monsters = {},
        ---敌对玩家序号
        No = no,
        ---怪物清空事件
        AllMonstersRemoveEvent = allMonstersRemoveEvent,
        ---所有数量生成完成事件
        AllMonstersCreateEvent = allMonstersCreateEvent,
        ---怪物数量
        CreateMonstersNumber = createMonstersNumber,
        ---怪物难度 按倍数增加属性 收益
        Difficulty = difficulty,
        ---AI难度 0自动施法 1根据行为判断
        AiDifficulty = aiDifficulty,
         ---清空怪物之后生成所需刷新时间/s  防守刷怪每刷一只时间
        Refresh = refresh,
        ---区域状态
        Open = false
    }

    return self
end
---给区域中添加预设怪
---@param rcname string 刷怪区名字
---@param monstersName string 怪物列表中的名字
function monsterZone:AddAreaMonsterNames(rcname, monstersName)
    table.insert(self.info[rcname].MonsterNames, monstersName)
    return self
end

---获取单位是哪个刷怪区的
---@param unitid number 单位ID
---@return string
function monsterZone:GetMonstersRCName(unitid)
    for k1, v1 in pairs(self.info) do
        for k2, v2 in pairs(v1.Monsters) do
            if k2 == unitid then
                return k1
            end
        end
    end
    return nil
end

---刷怪 定时刷怪 循环刷怪
---@param rcname string 区域名字
---@return any
function monsterZone:AreaMonstersFor(rcname)
    if next(self.info[rcname].MonsterNames) == nil then
        return
    end
    if self.info[rcname].Open==false then
        return
    end
    ---获取区域怪物数量
    local count = self.info[rcname].CreateMonstersNumber
    ---随机怪物预设的怪物
    local index = math.random(1, #self.info[rcname].MonsterNames)
    local MonsterNames = self.info[rcname].MonsterNames[index]

    local x = hrect.getX(self.info[rcname].rectID)
    local y = hrect.getX(self.info[rcname].rectID)

    for i = 1, count do
        local uid =
            hunit.create(
            {
                whichPlayer = hplayer.players[self.info[rcname].No],
                id = hslk.n2i(MonsterNames),
                x = x,
                y = y,
                qty = 1
            }
        )
        GTBar():hpSetPosition(uid)

        self.info[rcname].Monsters[uid] = {}
        ---怪物创建事件
        self.Monsters[MonsterNames].CreateEvent(uid)

        --注册单位死亡事件
        self.info[rcname].Monsters[uid].deadEventID =
            hevent.onDead(
            uid,
            function(evtData)
                local data = {}
                data["凶手"] = evtData.killUnit
                data["死亡单位"] = evtData.triggerUnit

                local id = self.info[rcname].Monsters[uid].deadEventID
                --执行怪物死亡事件
                self.Monsters[MonsterNames].DeadEvent(data)
                --删除区域中的怪物
                self.info[rcname].Monsters[uid] = nil
                --判断怪物是否全部死亡
                local flag = true
                for key, value in pairs(self.info[rcname].Monsters) do
                    if value ~= nil then
                        ---未死亡
                        flag = false
                        break
                    end
                end
                if flag then
                    ---全部死亡
                    self.info[rcname].AllMonstersRemoveEvent()
                    ---检测房间是否开启
                    if self.info[rcname].Open then
                        ---检测是否需要怪物刷新时间
                        if self.info[rcname].Refresh == 0 then
                            self:AreaMonstersFor(rcname)
                        else
                            ---等待刷怪
                            htime.setInterval(
                                self.info[rcname].Refresh,
                                function(curTimer)
                                    self:AreaMonstersFor(rcname)

                                    curTimer.destroy()
                                end
                            )
                        end
                    end
                end

                --删除事件
                hevent.deleteEvent(uid, CONST_EVENT.dead, id)
            end
        )
    end

    ---所有数量生成完成事件
    self.info[rcname].AllMonstersCreateEvent(self.info[rcname].Monsters)
    
    return self
end

---刷怪 防守刷怪
---@param rcname string 区域名字
---@return any
function monsterZone:AreaMonstersTime(rcname)
    if next(self.info[rcname].MonsterNames) == nil then
        return
    end
    if self.info[rcname].Open==false then
        return
    end
    ---获取区域怪物数量
    local count = self.info[rcname].CreateMonstersNumber
    ---随机怪物预设的怪物
    local index = math.random(1, #self.info[rcname].MonsterNames)
    local MonsterNames = self.info[rcname].MonsterNames[index]
    if MonsterNames==nil then
        return
    end
    local x = hrect.getX(self.info[rcname].rectID)
    local y = hrect.getX(self.info[rcname].rectID)

    local countIndex = 0
    ---定时循环创建怪物
    htime.setInterval(
        self.info[rcname].Refresh,
        function(curTimer)
            if countIndex == count then
                ---所有数量生成完成事件
                self.info[rcname].AllMonstersCreateEvent(self.info[rcname].Monsters)
                curTimer.destroy()
                return
            end

            local uid =
                hunit.create(
                {
                    whichPlayer = hplayer.players[self.info[rcname].No],
                    id = hslk.n2i(MonsterNames),
                    x = x,
                    y = y,
                    qty = 1
                }
            )
            GTBar():hpSetPosition(uid)
            self.info[rcname].Monsters[uid] = {}
            ---怪物创建事件
            self.Monsters[MonsterNames].CreateEvent(uid)

            --注册单位死亡事件
            self.info[rcname].Monsters[uid].deadEventID =
                hevent.onDead(
                uid,
                function(evtData)
                    local data = {}
                    data["凶手"] = evtData.killUnit
                    data["死亡单位"] = evtData.triggerUnit

                    local id = self.info[rcname].Monsters[uid].deadEventID
                    --执行怪物死亡事件
                    self.Monsters[MonsterNames].DeadEvent(data)
                    --删除区域中的怪物
                    self.info[rcname].Monsters[uid] = nil
                    --判断怪物是否全部死亡
                    local flag = true
                    for key, value in pairs(self.info[rcname].Monsters) do
                        if value ~= nil then
                            ---未死亡
                            flag = false
                            break
                        end
                    end
                    if flag then
                        ---全部死亡
                        self.info[rcname].AllMonstersRemoveEvent()
                        ---检测房间是否开启
                        -- if self.info[rcname].Open then

                        -- end
                    end

                    --删除事件
                    hevent.deleteEvent(uid, CONST_EVENT.dead, id)
                end
            )
            countIndex = countIndex + 1
        end
    )

    return self
end

---关闭刷怪
function monsterZone:StopAreaMonsters(rcname)
    self.info[rcname].Open = false

    return self
end
---开启刷怪
function monsterZone:OpenAreaMonsters(rcname)
    self.info[rcname].Open = true

    return self
end

---清空区域预设怪
function monsterZone:StopAreaMonsters(rcname)
    self.info[rcname].MonsterNames = {}

    return self
end

---清空区域内创建的所有怪 不触发事件
function monsterZone:StopAreaMonsters(rcname)
    for uid, value in pairs(self.info[rcname].Monsters) do
        local id = self.info[rcname].Monsters[uid].deadEventID
        hevent.deleteEvent(uid, CONST_EVENT.dead, id)
        hunit.del(uid,0)
    end
    return self
end
